package com.netease.nim.uikit.business.recent.holder;

import android.graphics.drawable.AnimationDrawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.business.recent.adapter.RecentContactAdapter;
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
import com.netease.nim.uikit.common.CommonUtil;
import com.netease.nim.uikit.common.framework.infra.Handlers;
import com.netease.nim.uikit.common.ui.drop.DropFake;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.ui.imageview.HeadImageView;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseQuickAdapter;
import com.netease.nim.uikit.common.ui.recyclerview.holder.BaseViewHolder;
import com.netease.nim.uikit.common.ui.recyclerview.holder.RecyclerViewHolder;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.common.util.sys.TimeUtil;
import com.netease.nim.uikit.impl.cache.NimUserInfoCache;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.superteam.SuperTeam;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.uinfo.UserService;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

public abstract class RecentViewHolder extends RecyclerViewHolder<BaseQuickAdapter, BaseViewHolder, RecentContact> {

    public RecentViewHolder(BaseQuickAdapter adapter) {
        super(adapter);
    }

    private int lastUnreadCount = 0;

    protected FrameLayout portraitPanel;

    protected HeadImageView imgHead;

    protected TextView tvNickname;

    private View sex_bg;
    private ImageView sex_logo;
    private TextView sex;
    private TextView vip;
    private TextView superVip;

    protected TextView tvMessage;

    protected TextView tvDatetime;

    // 消息发送错误状态标记，目前没有逻辑处理
    protected ImageView imgMsgStatus;

    protected View bottomLine;

    protected View topLine;

    // 未读红点（一个占坑，一个全屏动画）
    protected DropFake tvUnread;

    private ImageView imgUnreadExplosion;

    protected TextView tvOnlineState;

    private static Integer labelWidth;

    // 子类覆写
    protected abstract String getContent(RecentContact recent);

    @Override
    public void convert(BaseViewHolder holder, RecentContact data, int position, boolean isScrolling) {
        inflate(holder, data);
        refresh(holder, data, position);
    }

    public void inflate(BaseViewHolder holder, final RecentContact recent) {
        this.portraitPanel = holder.getView(R.id.portrait_panel);
        this.imgHead = holder.getView(R.id.img_head);
        this.tvNickname = holder.getView(R.id.tv_nickname);

        this.sex_bg = holder.getView(R.id.sex_bg);
        this.sex_logo = holder.getView(R.id.sex_logo);
        this.sex = holder.getView(R.id.tv_dt_age);
        this.vip = holder.getView(R.id.vip_bg);
        this.superVip = holder.getView(R.id.vip_super_bg);


        this.tvMessage = holder.getView(R.id.tv_message);
        this.tvUnread = holder.getView(R.id.unread_number_tip);
        this.imgUnreadExplosion = holder.getView(R.id.unread_number_explosion);
        this.tvDatetime = holder.getView(R.id.tv_date_time);
        this.imgMsgStatus = holder.getView(R.id.img_msg_status);
        this.bottomLine = holder.getView(R.id.bottom_line);
        this.topLine = holder.getView(R.id.top_line);
        this.tvOnlineState = holder.getView(R.id.tv_online_state);
        holder.addOnClickListener(R.id.unread_number_tip);
        this.tvUnread.setTouchListener(new DropFake.ITouchListener() {

            @Override
            public void onDown() {
                DropManager.getInstance().setCurrentId(recent);
                DropManager.getInstance().down(tvUnread, tvUnread.getText());
            }

            @Override
            public void onMove(float curX, float curY) {
                DropManager.getInstance().move(curX, curY);
            }

            @Override
            public void onUp() {
                DropManager.getInstance().up();
            }
        });
    }

    public void refresh(BaseViewHolder holder, RecentContact recent, final int position) {
        // unread count animation
        boolean shouldBoom = lastUnreadCount > 0 && recent.getUnreadCount() == 0; // 未读数从N->0执行爆裂动画;
        lastUnreadCount = recent.getUnreadCount();
        updateBackground(holder, recent, position);
        loadPortrait(recent);
        updateNickLabel(UserInfoHelper.getUserTitleName(recent.getContactId(), recent.getSessionType()));
        updateOnlineState(recent);
        updateMsgLabel(holder, recent);
        updateNewIndicator(recent);
        if (shouldBoom) {
            Object o = DropManager.getInstance().getCurrentId();
            if (o instanceof String && o.equals("0")) {
                imgUnreadExplosion.setImageResource(R.drawable.nim_explosion);
                imgUnreadExplosion.setVisibility(View.VISIBLE);
                Handlers.sharedHandler(holder.getContext()).post(() -> {
                    ((AnimationDrawable) imgUnreadExplosion.getDrawable()).start();
                    // 解决部分手机动画无法播放的问题（例如华为荣耀）
                    getAdapter().notifyItemChanged(getAdapter().getViewHolderPosition(position));
                });
            }
        } else {
            imgUnreadExplosion.setVisibility(View.GONE);
        }
    }

    private void updateBackground(BaseViewHolder holder, RecentContact recent, int position) {
        topLine.setVisibility(getAdapter().isFirstDataItem(position) ? View.GONE : View.VISIBLE);
        bottomLine.setVisibility(getAdapter().isLastDataItem(position) ? View.VISIBLE : View.GONE);
        holder.getConvertView().setBackgroundResource(CommonUtil.isStickyTagSet(
                recent) ? R.drawable.nim_recent_contact_sticky_selecter : R.drawable.nim_touch_bg);
    }

    protected void loadPortrait(RecentContact recent) {
        // 设置头像
        if (recent.getSessionType() == SessionTypeEnum.P2P) {
            imgHead.loadBuddyAvatar(recent.getContactId());
        } else if (recent.getSessionType() == SessionTypeEnum.Team) {
            Team team = NimUIKit.getTeamProvider().getTeamById(recent.getContactId());
            imgHead.loadTeamIconByTeam(team);
        } else if (recent.getSessionType() == SessionTypeEnum.SUPER_TEAM) {
            SuperTeam team = NimUIKit.getSuperTeamProvider().getTeamById(recent.getContactId());
            imgHead.loadSuperTeamIconByTeam(team);
        }
        if(recent.getContactId().equals("3d51dcd2f116464eabfa546233e3e804")){
            superVip.setVisibility(View.VISIBLE);
            superVip.setText("官方");
            superVip.setBackgroundResource(R.drawable.btn_guanfang);
            sex_bg.setVisibility(View.GONE);
            vip.setVisibility(View.GONE);
            tvDatetime.setVisibility(View.GONE);
        }else{
            tvDatetime.setVisibility(View.VISIBLE);
            NimUserInfo userInfo = NIMClient.getService(UserService.class).getUserInfo(recent.getContactId());
            if(userInfo == null){
                sex.setVisibility(View.GONE);
                sex_bg.setVisibility(View.GONE);
                superVip.setVisibility(View.GONE);
                vip.setVisibility(View.GONE);
                NimUserInfoCache.getInstance().getUserInfoFromRemote(recent.getContactId(), new RequestCallback<NimUserInfo>() {
                    @Override
                    public void onSuccess(NimUserInfo nimUserInfo) {
                        Map<String,Object> info = new Gson().fromJson(nimUserInfo.getExtension(),new TypeToken<Map<String,Object>>(){}.getType());
                        if(info != null){
                            String sexs = info.get("sex").toString();
                            String isVip = info.get("isVip").toString();
                            String isSupperVip = info.get("isSupperVip").toString();
                            String birthday = info.get("birthday").toString();
                            String age = getAge(birthday);
                            sex.setText(age);
                            sex.setVisibility(View.VISIBLE);
                            sex_bg.setVisibility(View.VISIBLE);
                            superVip.setVisibility(View.VISIBLE);
                            superVip.setText("SVIP");
                            superVip.setBackgroundResource(R.drawable.btn_vip_super);
                            vip.setVisibility(View.VISIBLE);
                            if(sexs.equals("男")){
                                sex_logo.setImageResource(R.drawable.man);
                                sex_bg.setBackgroundResource(R.drawable.btn_sex_man);
                            }else{
                                sex_logo.setImageResource(R.drawable.woman);
                                sex_bg.setBackgroundResource(R.drawable.btn_sex_woman);
                            }
                            if(!"是".equals(isVip)){
                                vip.setVisibility(View.GONE);
                            }
                            if(!"是".equals(isSupperVip)){
                                superVip.setVisibility(View.GONE);
                            }
                        }
                    }

                    @Override
                    public void onFailed(int i) {

                    }

                    @Override
                    public void onException(Throwable throwable) {

                    }
                });
            }
            else{
                Map<String,Object> info = new Gson().fromJson(userInfo.getExtension(),new TypeToken<Map<String,Object>>(){}.getType());
                if(info != null){
                    String sexs = info.get("sex").toString();
                    String isVip = info.get("isVip").toString();
                    String isSupperVip = info.get("isSupperVip").toString();
                    String birthday = info.get("birthday").toString();
                    String age = getAge(birthday);
                    sex.setText(age);
                    sex.setVisibility(View.VISIBLE);
                    sex_bg.setVisibility(View.VISIBLE);
                    superVip.setVisibility(View.VISIBLE);
                    superVip.setText("SVIP");
                    superVip.setBackgroundResource(R.drawable.btn_vip_super);
                    vip.setVisibility(View.VISIBLE);
                    if(sexs.equals("男")){
                        sex_logo.setImageResource(R.drawable.man);
                        sex_bg.setBackgroundResource(R.drawable.btn_sex_man);
                    }else{
                        sex_logo.setImageResource(R.drawable.woman);
                        sex_bg.setBackgroundResource(R.drawable.btn_sex_woman);
                    }
                    if(!"是".equals(isVip)){
                        vip.setVisibility(View.GONE);
                    }
                    if(!"是".equals(isSupperVip)){
                        superVip.setVisibility(View.GONE);
                    }
                }
            }
        }
    }

    public static String getAge(String birthDayStr){
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date birthDay = sdf.parse(birthDayStr);
            Calendar cal = Calendar.getInstance();
            if (cal.before(birthDay)) { //出生日期晚于当前时间，无法计算
                throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
            }
            int yearNow = cal.get(Calendar.YEAR);  //当前年份
            int monthNow = cal.get(Calendar.MONTH);  //当前月份
            int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
            cal.setTime(birthDay);
            int yearBirth = cal.get(Calendar.YEAR);
            int monthBirth = cal.get(Calendar.MONTH);
            int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
            int age = yearNow - yearBirth;   //计算整岁数
            if (monthNow <= monthBirth) {
                if (monthNow == monthBirth) {
                    if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
                }else{
                    age--;//当前月份在生日之前，年龄减一
                }
            }
            return age+"";
        }catch (Exception e){
            e.printStackTrace();
        }
        return "0";
    }


    private void updateNewIndicator(RecentContact recent) {
        int unreadNum = recent.getUnreadCount();
        if(recent.getContactId().equals("3d51dcd2f116464eabfa546233e3e804")){
            if("暂无新通知消息".equals(recent.getContent())){
                unreadNum = 0;
            }else{
                unreadNum = Integer.parseInt(recent.getContent().replace("你有","").replace("条系统消息",""));
            }
        }
        tvUnread.setVisibility(unreadNum > 0 ? View.VISIBLE : View.GONE);
        tvUnread.setText(unreadCountShowRule(unreadNum));
    }

    private void updateMsgLabel(BaseViewHolder holder, RecentContact recent) {
        // 显示消息具体内容
        MoonUtil.identifyRecentVHFaceExpressionAndTags(holder.getContext(), tvMessage, getContent(recent), -1, 0.45f);
        //tvMessage.setText(getContent());
        MsgStatusEnum status = recent.getMsgStatus();
        if (status == null) {
            imgMsgStatus.setVisibility(View.GONE);
        } else {
            switch (status) {
                case fail:
                    imgMsgStatus.setImageResource(R.drawable.nim_g_ic_failed_small);
                    imgMsgStatus.setVisibility(View.VISIBLE);
                    break;
                case sending:
                    imgMsgStatus.setImageResource(R.drawable.nim_recent_contact_ic_sending);
                    imgMsgStatus.setVisibility(View.VISIBLE);
                    break;
                default:
                    imgMsgStatus.setVisibility(View.GONE);
                    break;
            }
        }
        String timeString = TimeUtil.getTimeShowString(recent.getTime(), false);
        tvDatetime.setText(timeString);
    }

    protected String getOnlineStateContent(RecentContact recent) {
        return "";
    }

    protected void updateOnlineState(RecentContact recent) {
        if (recent.getSessionType() == SessionTypeEnum.Team || recent.getSessionType() == SessionTypeEnum.SUPER_TEAM) {
            tvOnlineState.setVisibility(View.GONE);
        } else {
            String onlineStateContent = getOnlineStateContent(recent);
            if (TextUtils.isEmpty(onlineStateContent)) {
                tvOnlineState.setVisibility(View.GONE);
            } else {
                tvOnlineState.setVisibility(View.VISIBLE);
                tvOnlineState.setText(getOnlineStateContent(recent));
            }
        }
    }

    protected void updateNickLabel(String nick) {
        if (labelWidth == null) {
            labelWidth = ScreenUtil.screenWidth - ScreenUtil.dip2px(120); // 减去固定的头像和时间宽度;
        }
        if (labelWidth > 0) {
            tvNickname.setMaxWidth(labelWidth);
        }
        tvNickname.setText(nick);
    }

    protected String unreadCountShowRule(int unread) {
        unread = Math.min(unread, 99);
        return String.valueOf(unread);
    }

    protected RecentContactsCallback getCallback() {
        return ((RecentContactAdapter) getAdapter()).getCallback();
    }
}
